package com.hospital.workstation.service.impl;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hospital.common.core.domain.PageQuery;
import com.hospital.common.core.domain.R;
import com.hospital.common.core.page.TableDataInfo;
import com.hospital.common.exception.ServiceException;
import com.hospital.common.utils.StringUtils;
import com.hospital.workstation.domain.MedicationRecord;
import com.hospital.workstation.domain.MedicationSummary;
import com.hospital.workstation.domain.PatientBaseInfo;
import com.hospital.workstation.domain.PharmaceuticalCareDetail;
import com.hospital.workstation.domain.bo.MedicationSummaryBo;
import com.hospital.workstation.domain.bo.PatientBaseInfoBo;
import com.hospital.workstation.domain.vo.MedicationRecordVo;
import com.hospital.workstation.domain.vo.MedicationSummaryVo;
import com.hospital.workstation.domain.vo.PatientBaseInfoVo;
import com.hospital.workstation.domain.vo.StatisticsVo;
import com.hospital.workstation.mapper.MedicationRecordMapper;
import com.hospital.workstation.mapper.MedicationSummaryMapper;
import com.hospital.workstation.mapper.PatientBaseInfoMapper;
import com.hospital.workstation.mapper.PharmaceuticalCareDetailMapper;
import com.hospital.workstation.service.IStatisticsService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.rowset.serial.SerialException;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 统计管理Service业务层处理
 *
 * @author whb
 * @date 2023-02-08
 */
@RequiredArgsConstructor
@Service
public class IStatisticsServiceImpl implements IStatisticsService {
    private final PatientBaseInfoMapper patientBaseInfoMapper;
    private final MedicationRecordMapper medicationRecordMapper;
    private final PharmaceuticalCareDetailMapper careDetailMapper;
    private final MedicationSummaryMapper summaryMapper;

    /**
     * 我的药历
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<PatientBaseInfoVo> queryMyMedicationPageList(PatientBaseInfoBo bo, PageQuery pageQuery) {
        Page<PatientBaseInfoVo> result = patientBaseInfoMapper.queryMyMedicationPageList(pageQuery.build(), buildQueryWrapper(bo));
        return TableDataInfo.build(result);
    }

    /**
     * 删除我的药历
     *
     * @param medicalRecordNo 流水号
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeMyMedicationRecord(Integer medicalRecordNo) {
        // 置空药历首页签名人信息
        MedicationRecord medicationRecord = medicationRecordMapper.selectOne(new LambdaQueryWrapper<MedicationRecord>()
            .eq(MedicationRecord::getMedicalRecordNo, medicalRecordNo));
        if (ObjectUtil.isNotNull(medicationRecord)) {
            medicationRecord.setSigner(null);
            medicationRecordMapper.updateById(medicationRecord);
        }
        // 置空药学监护详情表签名人信息
        List<PharmaceuticalCareDetail> careDetailList = careDetailMapper.selectList(new LambdaQueryWrapper<PharmaceuticalCareDetail>()
            .eq(PharmaceuticalCareDetail::getMedicalRecordNo, medicalRecordNo));
        if (careDetailList.size() > 0) {
            careDetailList.stream().forEach(pharmaceuticalCareDetail -> {
                pharmaceuticalCareDetail.setSigner(null);
            });
            careDetailMapper.updateBatchById(careDetailList);
        }
        // 置空药历小结的签名人信息
        MedicationSummary medicationSummary = summaryMapper.selectOne(new LambdaQueryWrapper<MedicationSummary>()
            .eq(MedicationSummary::getMedicalRecordNo, medicalRecordNo));
        if (ObjectUtil.isNotNull(medicationSummary)) {
            medicationSummary.setSigner(null);
            summaryMapper.updateById(medicationSummary);
        }
    }

    /**
     * 分页查询工作量统计
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<StatisticsVo> queryStatisticsWorkload(MedicationSummaryBo bo, PageQuery pageQuery) {
        Page<StatisticsVo> result = summaryMapper.queryWorkload(pageQuery.build(), buildQueryWrapper(bo));
        return TableDataInfo.build(result);
    }

    /**
     * 查询工作量统计
     *
     * @param bo
     * @return
     */
    @Override
    public List<StatisticsVo> queryStatisticsWorkloadList(MedicationSummaryBo bo) {
        return summaryMapper.queryWorkloadList(buildQueryWrapper(bo));
    }

    /**
     * 删除我的药历
     *
     * @param medicalRecordNo 病历号
     * @return
     */
    @Override
    public R<Void> del(Integer medicalRecordNo) {
        // 1.查询我的药历
        MedicationSummary medicationSummary = summaryMapper.selectOne(new LambdaQueryWrapper<MedicationSummary>()
            .eq(MedicationSummary::getMedicalRecordNo, medicalRecordNo));
        if (ObjectUtil.isNull(medicationSummary)) {
            throw new ServiceException("我的药历已不存在");
        }
        // 2.删除我的药历
        boolean flag = summaryMapper.deleteById(medicationSummary.getId()) > 0;
        return flag ? R.ok("删除成功") : R.fail("删除失败");
    }

    /**
     * 药历查询条件
     *
     * @param bo
     * @return
     */
    private Wrapper<PatientBaseInfo> buildQueryWrapper(PatientBaseInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        Map<String, Object> dateMap = getDate((String) params.get("beginDate"), (String) params.get("endDate"));
        QueryWrapper<PatientBaseInfo> qw = Wrappers.query();
        qw.isNotNull("hms.signer")
            .isNotNull("pbi.discharge_time")
            .like(StringUtils.isNotBlank(bo.getNickName()), "hms.signer", bo.getNickName())
            .like(StringUtils.isNotBlank(bo.getMedicareNo()), "pbi.medicare_no", bo.getMedicareNo())
            .like(StringUtils.isNotBlank(bo.getPatientName()), "pbi.patient_name", bo.getPatientName())
            .eq(StringUtils.isNotBlank(bo.getGuardianLevel()), "pbi.guardian_level", bo.getGuardianLevel())
            .between("pbi.discharge_time", dateMap.get("beginDate") + " 00:00:00", dateMap.get("endDate") + " 23:59:59")
            .between(ObjectUtil.isNotNull(params.get("beginAge")) && ObjectUtil.isNotNull(params.get("endAge")), "pbi.patient_age"
                , params.get("beginAge"), params.get("endAge"))
            .and(StringUtils.isNotBlank(bo.getSummaryState()) && StringUtils.equals("0", bo.getSummaryState()), w -> w.eq("hms.summary_state", "0").or().isNull("hms.summary_state"))
            .eq(StringUtils.isNotBlank(bo.getSummaryState()) && StringUtils.equals("1", bo.getSummaryState()), "hms.summary_state", "1")
            .ne("hms.del_flag", "2")
            .orderByDesc("pbi.admission_time");
        return qw;
    }

    /**
     * 工作量统计查询条件
     *
     * @param bo
     * @return
     */
    private Wrapper<MedicationSummary> buildQueryWrapper(MedicationSummaryBo bo) {
        Map<String, Object> params = bo.getParams();
        Map<String, Object> dateMap = getDate((String) params.get("beginDate"), (String) params.get("endDate"));
        QueryWrapper<MedicationSummary> qw = Wrappers.query();
        qw.isNotNull("hms.signer")
            .isNotNull("hms.out_hospital_date")
            .ne("su.del_flag", "2")
            .like(StringUtils.isNotBlank(bo.getSigner()), "hms.signer", bo.getSigner())
            .between("hms.out_hospital_date", dateMap.get("beginDate") + " 00:00:00", dateMap.get("endDate") + " 23:59:59")
            .groupBy("hms.signer")
            .groupBy("dept_name");
        return qw;
    }

    /**
     * 查询日期
     */
    private Map<String, Object> getDate(String beginDate, String endDate) {
        Map<String, Object> dateMap = new HashMap<>();
        // 查询日期为空，默认为最近一个月
        if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) {
            LocalDate nowDate = LocalDate.now(); // 当前日期
            LocalDate beforeMonthDate = nowDate.minus(1, ChronoUnit.MONTHS); // 一个月以前的日期
            beginDate = beforeMonthDate.toString();
            endDate = nowDate.toString();
        }
        dateMap.put("beginDate", beginDate);
        dateMap.put("endDate", endDate);
        return dateMap;
    }
}
